#include <iostream>

#include "ClosestVertexSelector.h"
#include "Tetrahedron.h"
#include "TetrahedronIntersection.h"
#include "Triangle.h"
#include "Node.h"
#include "Simplex.h"
#include "FEMModel.h"
#include "EdgeIntersection.h"

TetrahedronIntersection::TetrahedronIntersection ()
{
	complete_b_ = false;
	tetra_ =0;
	triangle_ =0;
	sweep_count_ = 0;
}

Triangle *TetrahedronIntersection::GetTriangle ()
{
	assert (edges_.Size () <= 12);
	bool found [4] = {0,0,0,0};

	for (int i = edges_.Size (); i--;)
	{
		for (int j = 0; j < 4; j++)
		{
			if (tetra_->GetNode(j) == edges_[i]->closest_)
			{
				found [j] = true;
			}
		}
	}

	int count =0 ;
	int notfoundidx = -1;
	for (int i=0; i<  4; i ++)
		if (found[i])
			count ++;
		else
			notfoundidx = i;

	if (count < 3)
		return 0;

	if (count ==4)
	{
		cerr << "DEGENERATE CASE\n";
		return tetra_->GetTriangle (0);
	}
	return tetra_->GetTriangle (notfoundidx);
}

/**
current implementation is too crude. 
*/
LinkArray<Tetrahedron> TetrahedronIntersection::AdjacentTetras ()
{
	LinkArray<Tetrahedron> tets;

	if (edges_.Size ())
		for (int i=0; i < 4; i++)
		{
			Triangle* t = tetra_->GetTriangle(i);

			if (t->Mate ())
				tets.Push (t->Mate ()->Tetra ());
		}
		return tets;  
}


void TetrahedronIntersection::Print (std::ostream &cout )const
{
	for (int i =0; i < edges_.Size (); i++)
	{
		edges_[i]->Print(cout);
	}
	if (triangle_)
		cout << " selected triangle " << triangle_->Number () 
		<< " set = " << triangle_->GetSet () ; 
	cout << endl;
}

/*
check if pointers are kosher.
*/
bool TetrahedronIntersection::Valid () const
{
	bool v = tetra_->Valid ();
	for (int j  = edges_.Size (); j--;)
	{
		v = v && edges_[j]->Valid ();
	}
	return v;
}
